#include <iostream>
#include <fstream>      // file reading
#include <netinet/in.h> // htonl, htons
#include <stdlib.h>     // EXIT_FAILURE
#include <stdio.h>
#include <string.h>
#include <sstream>
#include <fcntl.h>

using namespace std;

#define LINK_RESPONSE 'R'
#define LINK_REQUEST  'L'
#define LINK_UPDATE   'U'
#define TRACE         'T'
#define UNDEFINED     'X'

class Packet {
    public:
        Packet();
		Packet( char           type,
				unsigned long  ttl,
				unsigned long  src_ip,
				unsigned short src_port,
				unsigned long  dest_ip,
				unsigned short dest_port,
				unsigned long  seq,
				string         nodes );

		char           get_type();
		unsigned long  get_ttl();
		unsigned long  get_src_ip();
		unsigned short get_src_port();
		unsigned long  get_dest_ip();
		unsigned short get_dest_port();
		unsigned long  get_seq();
		string         get_nodes();
        
		void set_type(char type);
		void set_ttl(unsigned long ttl);
		void set_src_ip(unsigned long src_ip);
		void set_src_port(unsigned short src_port);
		void set_dest_ip(unsigned long dest_ip);
		void set_dest_port(unsigned short dest_port);
		void set_seq(unsigned long seq);
		void set_nodes(string nodes);
        
        void send_packet(int sockfd, struct sockaddr_in sockaddr);
        static Packet* receive_packet(int sockfd, 
        	struct sockaddr_in* sockaddr, int msg_size, bool isBlocking);
        
        void print_packet();
        
    private:
        string convert_long(unsigned long num);
		string convert_short(unsigned short num);
        static Packet* reconstruct_packet(string packet);
        
		char           type;
		unsigned long  ttl, src_ip, dest_ip, seq;
		unsigned short src_port, dest_port;
		string         nodes;
};
